#######################################################
# The class of DEVSInterfaces 
# Author: moonho.hwang@gmail.com
#   Date: Oct.19.2011
#######################################################
from DEVSBase import *

class Port(HierNamedObj):
   '''A port class which has two sets of output ports and input ports'''
   def __init__(self, n, parent=None):
      '''constructor'''
      HierNamedObj.__init__(self, n, parent)

   def __eq__(self, obj):
      '''equivalence checker operator'''
      return self.__class__ == obj.__class__ and self.name == obj.name

   def __str__(self):
      return HierNamedObj.__str__(self)

   def __hash__(self):
      '''return address of self because same port name but different'''
      return id(self) 
#end of class Port
 
class InputPort(Port):
   '''The class of input ports'''
   def __init__(self, n, parent=None):
      '''constructor'''
      Port.__init__(self, n, parent)
#end of class InputPort

class OutputPort(Port):
   '''The class of output ports'''
   def __init__(self, n, parent=None):
      '''constructor'''
      Port.__init__(self, n, parent)
#end of class InputPort
 
class XY:
   '''The interface class for DEVS communications'''
   def __init__(self):
      '''input ports and output ports sorted by their names'''
      self.IP = dict()
      self.OP = dict()

   def addInputPorts(self,*args):
      '''add an input port having ipname'''
      for ipname in args:
         if ipname in self.IP:
            print "%s already exists in IP"%ipname
         else:
            ip = InputPort(ipname, self)
            self.IP[ipname] = ip
   
#   def IP(self, ipname):
#      '''get an input port whose name is ipname'''
#      if ipname in self.IP: return self.IP[ipname]
#      else: return None

   def to_IP_s(self):
      '''convert IPs to a string'''
      return "IP=" + str(self.IP.keys())

   def addOutputPorts(self, *args):
      '''add an output port having opname'''
      for opname in args:
         if opname in self.OP:
            print "%s already exists in OP"%opname
         else:
            op = OutputPort(opname, self)
            self.OP[opname]=op

#   def OP(self, opname):
#      '''get an output port whose name is opname'''
#      if opname in self.OP: return self.OP[opname]
#      else: return None

   def to_OP_s(self):
      '''convert OPs to a string'''
      return "OP=" + str(self.OP.keys())
#end of class XY

class PortValue:
   '''the class for (port,value)'''
   def __init__(self, port, value=None):
      if isinstance(port, Port) == False:
         raise Exception("%s is not Port!"%port.__class__)

      self.port, self.value = port, value

   def __eq__(self, obj):
      '''equivalence checker'''
      return self.__class__ == obj.__class__ and \
            self.port == obj.port and self.value == obj.value

   def __str__(self):
      '''return the string "port:value" '''
      s = str(self.port)
      if self.value != None: s = s + ":" + str(self.value)
      return s

   def __hash__(self):
      return hash(str(self))

#---- test code ------
if __name__ == '__main__' :
    ip = InputPort("ip0")
    print ip.__class__
    print("ip=%s\n"%str(ip))
    op = OutputPort("op0")
    print op.__class__
    print("op=%s\n"% str(op))
   
